package com.idp.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.idp.common.enums.UserTypeEnum;
import com.idp.common.error.SystemException;
import com.idp.common.model.LoginInfo;
import com.idp.common.token.SysUserAuthenticationToken;
import com.idp.common.token.service.TokenService;
import com.idp.system.dto.SysButtonDto;
import com.idp.system.dto.SysMenuDto;
import com.idp.system.dto.SysUserDto;
import com.idp.system.entity.SysButtonEntity;
import com.idp.system.entity.SysMenuEntity;
import com.idp.system.entity.SysUserEntity;
import com.idp.system.mapper.SysButtonMapper;
import com.idp.system.mapper.SysMenuMapper;
import com.idp.system.mapper.SysUserMapper;
import com.idp.system.service.LoginService;
import com.idp.system.utils.MenuUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 登录Service实现类
 * @author king
 */
@Service
public class LoginServiceImpl implements LoginService {

	private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class);

	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private SysMenuMapper sysMenuMapper;
	@Autowired
	private SysButtonMapper sysButtonMapper;
	@Autowired
	private TokenService tokenService;
	@Autowired
	private AuthenticationManager authenticationManager;

	@Override
	public LoginInfo login(SysUserDto sysUserDto) {

		SysUserAuthenticationToken authenticationToken = new SysUserAuthenticationToken(sysUserDto.getUname(), sysUserDto.getPwd());
		Authentication authentication = authenticationManager.authenticate(authenticationToken);

		LoginInfo loginInfo = (LoginInfo) authentication.getPrincipal();
		loginInfo.setUserType(UserTypeEnum.PC.code);
		tokenService.saveToken(loginInfo);

		return loginInfo;
	}

	@Override
	@Cacheable(cacheNames = "ruleMenuCache", key = "'user'+#userId")
	public Map<String, Object> getLoginRuleMenus(String userId) {

		Map<String, Object> map = new HashMap<String, Object>();

		SysUserEntity user = sysUserMapper.selectById(userId);
		map.put("account", user.getUname());

		if(user != null && UserTypeEnum.ADMIN.code.equals(user.getUserType())) {

			List<SysMenuEntity> menuList = sysMenuMapper.selectList(new LambdaQueryWrapper<>());
			List<SysMenuDto> menuDtoList = BeanUtil.copyToList(menuList, SysMenuDto.class);
			List<SysMenuDto> resultMenus = MenuUtil.getMenusForTree(menuDtoList);
			map.put("menus", resultMenus);
			List<String> menuRouters = menuList.stream().map(SysMenuEntity::getMenuUrl).collect(Collectors.toList());
			map.put("menuRouters", String.join("|", menuRouters));
		} else {

			List<SysMenuDto> ruleMenus = sysMenuMapper.findRuleMenus(userId);
			map.put("menus", MenuUtil.getMenusForTree(ruleMenus));
			List<String> menuRouters = ruleMenus.stream().map(SysMenuDto::getMenuUrl).collect(Collectors.toList());
			map.put("menuRouters", String.join("|", menuRouters));
		}

		return map;
	}

	@Override
	@Cacheable(cacheNames = "ruleButtonCache", key = "'user'+#userId")
	public List<SysButtonDto> getLoginRuleButtons(String userId) {

		SysUserEntity user = sysUserMapper.selectById(userId);

		if(user != null && UserTypeEnum.ADMIN.code.equals(user.getUserType())) {

			List<SysButtonEntity> btnList = sysButtonMapper.selectList(new LambdaQueryWrapper<>());

			return BeanUtil.copyToList(btnList, SysButtonDto.class);
		} else {

			List<SysButtonDto> ruleButtons = sysButtonMapper.findRuleButtons(userId);

			return ruleButtons;
		}
	}

	@Override
	@CacheEvict(cacheNames = "ruleMenuCache", key = "'user'+#userId")
	public void deleteRuleMenusCache(String userId) {

	}

	@Override
	@CacheEvict(cacheNames = "ruleButtonCache", key = "'user'+#userId")
	public void deleteRuleButtonsCache(String userId) {

	}
}
